// 面向过程 面向函数
// 函数式编程

// 命令式编程：原生js开发或jquery通过操作DOM对象来完成数据的更改
// 声明式编程：框架底层已经封装好模块帮助我们完成DOM的操作，只需去声明即可使用 vue react angular
// 编程范式：命令式编程与声明式编程
// 编程范式：面向对象的编程与面向过程的编程
// 面向过程方式第一个公民即函数，函数式编程

const nums = [10,20,111,222,444,40,50]

//1. 从nums 数组中取出小于100的数

let newNums = []
for (const n of nums) {
    if (n < 100){
        newNums.push(n)
    }
}
console.log(newNums);

// 2. 从（1）要求中小于100的数都乘以2
let newNewNums = []
for (const n of newNums) {
    newNewNums.push(n * 2)
}
console.log(newNewNums);

// 3. 从（2）要求 把所有的数累加，得到最终结果
let total = 0
for (const n of newNewNums) {
    total += n 
}

console.log(total)

//封装了一些函数用来实现上面的一些效果
// 1）filter函数的使用
// 参数是一个回调函数，数组有多少个成员，就回调多少次
let newNums1 = nums.filter(function(n){
    // 匿名函数中，有一个参数n，是每一次回调的数组成员，第一次n就为10，第二次就为第二个成员20
    // 匿名函数必须返回的是布尔值，true返回n进入到新的数组中
    return n < 100
})

console.log(newNums1)

// 2) map函数的使用
// 它可以对数组中每个内容进行操作
// 参数为匿名回调函数
let newNewNums1 = newNums1.map(function (n) {
    // 参数为n，指代每次回调的数组成员
    return n * 2
})

console.log(newNewNums1);

// 3) reduce函数，第一个参数为匿名回调函数，第二个参数为默认值
// 作用就对数组中所有内容进行汇总

let total1 = newNewNums1.reduce(function(preValue,n){
    // 匿名回调函数中，第一个参数preValue 指代上一次返回的值
    // 第二个参数为n，本次回调进入的数组成员
    return preValue + n
},0)

console.log(total1)
// 函数式编程

// 把三个需求进行综合，一起提出
let totalnums = nums.filter(function(n){
    return n < 100
}).map(function(n){
    return n * 2
}).reduce(function(preValue,n){
    return preValue + n
},0)

console.log(totalnums)

// es6 语法 匿名函数 箭头函数
// 简写规则
// 1）参数如果为一个，可以省略括号
// 2）函数体中只有一行return代码，可以省略大括号和return关键字 
let totalnums2 = nums.filter(n => n < 100).map(n => n * 2)
.reduce((preValue,n)=> preValue + n,0)

console.log(totalnums2);


